# -*- coding: utf-8 -*-

###################
#   miniTH
#   This program serves for serial change of photos size, to put watermarks
#   and at the same time for making thumbnails.
#   It can be useful for quick processing of big amount of pictures in order to put
#   them in web galleries or on websites.
#   Copyright (C) 2011 DooBLER
#
#   This program is free software: you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
###################

###################
# svn: $Id: MyMarchingAntsRectItem.py 19 2011-08-15 13:41:38Z MrDooBLER@gmail.com $
# Author: DooBLER http://doobler.net
###################


from PySide import QtCore
from PySide import QtGui

class MyMarchingAntsRectItem(QtCore.QObject, QtGui.QGraphicsRectItem):

    # sygnały
    sigMoved = QtCore.Signal(QtCore.QPointF)
    sigSizeChanged = QtCore.Signal(QtCore.QPointF)
    sigDelSelection = QtCore.Signal(bool)

    def __init__(self, parent=None, *args, **kwargs):
        QtCore.QObject.__init__(self)
        QtGui.QGraphicsRectItem.__init__(self, parent, *args, **kwargs)

        self.ramka = 1
        self.underMouse = False
        self.skala = 1

        self.proportions = 0

        self.scalePoint = 0

        #self.setFlag(QtGui.QGraphicsItem.ItemIgnoresTransformations)
        self.setFlag(QtGui.QGraphicsItem.ItemIsMovable)
        self.setFlag(QtGui.QGraphicsItem.ItemIsFocusable)
  
        self.setAcceptHoverEvents(True)

        self.setPen(self._getPedzel(1))

        # timer
        self.timer = QtCore.QTimer(None)
        self.timer.timeout.connect(self._timerTimeout)
        self.timer.start(300)

        # menu
        self.menu = QtGui.QMenu()
        allAction = self.menu.addAction(self.tr('Select all'))
        widthAction = self.menu.addAction(self.tr('Full width'))
        heightAction = self.menu.addAction(self.tr('Full height'))
        self.menu.addSeparator()
        delAction = self.menu.addAction(self.tr('Delete selection'))

        allAction.triggered.connect(self.allActionTriggered)
        widthAction.triggered.connect(self.widthActionTriggered)
        heightAction.triggered.connect(self.heightActionTriggered)
        delAction.triggered.connect(self.delActionTriggered)



    def allActionTriggered(self):
        self.setPos(0, 0)
        self.sigMoved.emit(QtCore.QPointF(0, 0))
        w = self.scene().sceneRect().width()-1
        h = self.scene().sceneRect().height()-1
        self.setRect(QtCore.QRectF(0, 0, w, h))
        self.sigSizeChanged.emit(QtCore.QPointF(w, h))

    def widthActionTriggered(self):
        py = self.pos().y()
        height = self.rect().height()
        w = self.scene().sceneRect().width()-1

        self.setPos(0, py)
        self.sigMoved.emit(QtCore.QPointF(0, py))
        self.setRect(QtCore.QRectF(0, 0, w, height))
        self.sigSizeChanged.emit(QtCore.QPointF(w, height))

    def heightActionTriggered(self):
        px = self.pos().x()
        width = self.rect().width()
        h = self.scene().sceneRect().height()-1
        
        self.setPos(px, 0)
        self.sigMoved.emit(QtCore.QPointF(px, 0))
        self.setRect(QtCore.QRectF(0, 0, width, h))
        self.sigSizeChanged.emit(QtCore.QPointF(width, h))

    def delActionTriggered(self):
         self.sigDelSelection.emit(False)


    def contextMenuEvent(self, event):
        self.menu.exec_(event.screenPos())


    def setZoom(self, zoom):
        """
            Ustawianie skali
        """
        self.skala = zoom
        self.update()


    def paint(self, painter, option, widget):
        painter.setPen(self.pen())

        # automatyczne sprawdzanie skali - dość wolne
#        aaa = self.scene().views()
#        skala = aaa[0].matrix().m11()
#        if skala != self.skala:
#            self.skala = skala
#            print skala

        painter.drawRect(self.rect())

        if self.underMouse :
            mybrush1 = QtGui.QBrush()
            mybrush1.setStyle(QtCore.Qt.SolidPattern)
            mybrush1.setColor(QtGui.QColor(127, 127, 127, 150))

            painter.setBrush(mybrush1)

            top = self.rect().top()
            left = self.rect().left()
            width = self.rect().width()
            height = self.rect().height()

            # top left
#            if self.scalePoint == 0 or self.scalePoint == 1:
#                painter.drawRect(left+2, top+2, 10, 10 )
            # top
#            if self.scalePoint == 0 or self.scalePoint == 2 :
#                painter.drawRect(left+14, top+2, width-28, 10 )
            # top right
#            if self.scalePoint == 0 or self.scalePoint == 3 :
#                painter.drawRect(left+width-12, top+2, 10, 10 )
            # left
#            if self.scalePoint == 0 or self.scalePoint == 4 :
#                painter.drawRect(left+2, top+14, 10, height-28 )
            #right
            if self.scalePoint == 0 or self.scalePoint == 5 :
                painter.drawRect(left+width-12, top+14, 10, height-28 )
            # bottom left
#            if self.scalePoint == 0 or self.scalePoint == 6 :
#                painter.drawRect(left+2, top+height-12, 10, 10 )
            # bottom
            if self.scalePoint == 0 or self.scalePoint == 7 :
                painter.drawRect(left+14, top+height-12, width-28, 10 )
            # bottom right
#            if self.scalePoint == 0 or self.scalePoint == 8 :
#                painter.drawRect(left+width-12, top+height-12, 10, 10 )

    def _whatScalePoint(self, pos):
        px = pos.x()
        py = pos.y()
        top = self.rect().top()
        left = self.rect().left()
        width = self.rect().width()
        height = self.rect().height()


        back = self.scalePoint

#        if py <= top+12:
#            if px <= left+12:
#                self.scalePoint = 1
#            elif px >= left+14 and px <= left+width-14:
#                self.scalePoint = 2
#            elif px >= left+width-12:
#                self.scalePoint = 3
#        elif py >= top+14 and py <= top+height-14:
#            if px <= left+12:
#                self.scalePoint = 4
#            elif px >= left+width-12:
#                self.scalePoint = 5
#            else:
#                self.scalePoint = 0
#        elif py >= top+height-12:
#            if px <= left+12:
#                self.scalePoint = 6
#            elif px >= left+14 and px <= left+width-14:
#                self.scalePoint = 7
#            elif px >= left+width-12:
#                self.scalePoint = 8
#        else:
#            self.scalePoint = 0
        
        # okrojona wersja
        if py >= top+14 and py <= top+height-14:
            if px >= left+width-12:
                self.scalePoint = 5
            else:
                self.scalePoint = 0
        elif py >= top+height-12:
            if px >= left+14 and px <= left+width-14:
                self.scalePoint = 7
            else:
                self.scalePoint = 0
        else:
            self.scalePoint = 0


    

        if back != self.scalePoint:
            self.update()


    def hoverEnterEvent(self, event):
        self.underMouse = True
        self.update()

    def hoverLeaveEvent(self, event):
        self.underMouse = False
        self.update()

    def hoverMoveEvent(self, event):
        self._whatScalePoint(event.pos())


    def mousePressEvent(self, event):
        self._whatScalePoint(event.pos())
        QtGui.QGraphicsRectItem.mousePressEvent(self, event)

    def mouseMoveEvent(self, event):
        pos = event.pos()

 
        top = self.rect().top()
        left = self.rect().left()
        width = self.rect().width()
        height = self.rect().height()

        # top left
        if self.scalePoint == 1:
            pass
        # top
        elif self.scalePoint == 2 :
            pass
        # top right
        elif self.scalePoint == 3 :
            pass
        # left
        elif self.scalePoint == 4 :
            pass
        #right
        elif self.scalePoint == 5 :
            newrect = self.setWidth(pos.x()+5)

            self.sigSizeChanged.emit(newrect)
        # bottom left
        elif self.scalePoint == 6 :
            pass
        # bottom
        elif self.scalePoint == 7 :
            newrect = self.setHeight(pos.y()+5)

            self.sigSizeChanged.emit(newrect)
        # bottom right
        elif self.scalePoint == 8 :
            #self.setRect(QtCore.QRectF(top, left, pos.x(), pos.y()))
            pass
        else:
            # przemieszczanieqg
            newPos = QtCore.QPointF(self.mapToParent(event.pos() - QtGui.QMatrix().map(event.buttonDownPos(QtCore.Qt.LeftButton))))

            if newPos.x() < 0:
                newPos.setX(0)

            if newPos.y() < 0:
                newPos.setY(0)

            if newPos.x() + width > self.scene().sceneRect().width():
                newPos.setX(self.scene().sceneRect().width() - width - 1)

            if newPos.y() + height > self.scene().sceneRect().height():
                newPos.setY(self.scene().sceneRect().height() - height - 1)

            self.setPos(newPos)

            self.sigMoved.emit(newPos)

            #QtGui.QGraphicsRectItem.mouseMoveEvent(self, event)


    def setProportions(self, value):
        self.proportions = value

    def setWidth(self, width):
        height = self.rect().height()

        if width < 50:
            width = 50
        elif width > self.scene().sceneRect().width() - self.scenePos().x()-1:
            width = self.scene().sceneRect().width() - self.scenePos().x()-1

        if self.proportions > 0:
            height = round(float(width) / self.proportions)
            if height < 50:
                height = 50
                width = round(float(height) * self.proportions)
            elif height > self.scene().sceneRect().height() - self.scenePos().y() - 1:
                height = self.scene().sceneRect().height() - self.scenePos().y() - 1
                width = round(float(height) * self.proportions)


        return self.setSize(QtCore.QPointF(width, height))

    def setHeight(self, height):
        width = self.rect().width()

        if height < 50:
            height = 50
        elif height > self.scene().sceneRect().height() - self.scenePos().y() - 1:
            height = self.scene().sceneRect().height() - self.scenePos().y() - 1

        if self.proportions > 0:
            width = round(float(height) * self.proportions)
            if width < 50:
                width = 50
                height = round(float(width) / self.proportions)
            elif width > self.scene().sceneRect().width() - self.scenePos().x()-1:
                width = self.scene().sceneRect().width() - self.scenePos().x()-1
                height = round(float(width) / self.proportions)

        return self.setSize(QtCore.QPointF(width, height))

    def setSize(self, size):
        self.setRect(self.rect().top(), self.rect().left(), size.x(), size.y())
        return size

    def getMax(self):
        sx = self.scenePos().x()
        sy = self.scenePos().y()
        sw = self.scene().sceneRect().width()
        sh = self.scene().sceneRect().height()
        w = self.rect().width()
        h = self.rect().height()

        if self.proportions > 0:
            wmax = sw-sx
            hmax = sh-sy
            wmax2 = float(hmax) * self.proportions
            hmax2 = float(wmax) / self.proportions

            if wmax2 > wmax:
                hmax = round(hmax2)
            elif hmax2 > hmax:
                wmax = round(wmax2)

            return QtCore.QRectF(sw-w, sh-h, wmax, hmax)
        else:
            return QtCore.QRectF(sw-w, sh-h, sw-sx, sh-sy)


    def _timerTimeout(self):
        """
        Funkcja timera
        """
        self.ramka +=1
        if self.ramka > 4:
            self.ramka = 1

        self.setPen(self._getPedzel(self.ramka))


    def _getPedzel(self, step = 1):
        """
        Generowanie pędzla "marhing ants"
        """
        sp = 4/self.skala
        radialGrad = QtGui.QLinearGradient(QtCore.QPointF(0, 0),QtCore.QPointF(sp, sp))
        if step == 1:
            radialGrad.setColorAt(0, QtCore.Qt.white)
            radialGrad.setColorAt(0.499, QtCore.Qt.white)
            radialGrad.setColorAt(0.5, QtCore.Qt.black)
            radialGrad.setColorAt(0.999, QtCore.Qt.black)
            radialGrad.setColorAt(1, QtCore.Qt.white)
        elif step == 2:
            radialGrad.setColorAt(0, QtCore.Qt.black)
            radialGrad.setColorAt(0.249, QtCore.Qt.black)
            radialGrad.setColorAt(0.25, QtCore.Qt.white)
            radialGrad.setColorAt(0.749, QtCore.Qt.white)
            radialGrad.setColorAt(0.75, QtCore.Qt.black)
            radialGrad.setColorAt(1, QtCore.Qt.black)
        elif step == 3:
            radialGrad.setColorAt(0, QtCore.Qt.black)
            radialGrad.setColorAt(0.499, QtCore.Qt.black)
            radialGrad.setColorAt(0.5, QtCore.Qt.white)
            radialGrad.setColorAt(0.999, QtCore.Qt.white)
            radialGrad.setColorAt(1, QtCore.Qt.black)
        else:
            radialGrad.setColorAt(0, QtCore.Qt.white)
            radialGrad.setColorAt(0.249, QtCore.Qt.white)
            radialGrad.setColorAt(0.25, QtCore.Qt.black)
            radialGrad.setColorAt(0.749, QtCore.Qt.black)
            radialGrad.setColorAt(0.75, QtCore.Qt.white)
            radialGrad.setColorAt(1, QtCore.Qt.white)

        radialGrad.setSpread(QtGui.QGradient.RepeatSpread)
        return QtGui.QPen(QtGui.QBrush(radialGrad), 0)
